/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dailyyoga.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

import com.dailyyoga.bitmapManager.RecyclingBitmapDrawable;

/**
 * Sub-class of ImageView which automatically notifies the drawable when it is
 * being displayed.
 */
public class RecyclingImageView extends ImageView {
	
	String mPath;
	
	public RecyclingImageView(Context context) {
		super(context);
	}

	public RecyclingImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected Parcelable onSaveInstanceState() {
		Log.d("RecyclingImageView", "onSaveInstanceState");
		return super.onSaveInstanceState();
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		if (getDrawable() == null && mPath != null) {
			setImageDrawable(new RecyclingBitmapDrawable(getResources(),
					BitmapFactory.decodeFile(mPath)));
		}
	}

	public void setCachePath(String path) {
		mPath = path;
	}

	/**
	 * @see android.widget.ImageView#onDetachedFromWindow()
	 */
	@Override
	protected void onDetachedFromWindow() {

		Log.d("RecyclingImageView",
				"// This has been detached from Window, so clear the drawable");
		setImageDrawable(null);
		super.onDetachedFromWindow();

	}

	@Override
	public void setImageBitmap(Bitmap bm) {

		Log.d("RecyclingImageView", "RecyclingImageView setImageBitmap");
		super.setImageBitmap(bm);
	}

	@Override
	protected void onDraw(Canvas canvas) {

		Drawable drawable = getDrawable();

		if (drawable instanceof RecyclingBitmapDrawable) {

			Bitmap bitmap = ((RecyclingBitmapDrawable) drawable).getBitmap();

			if (bitmap != null && bitmap.isRecycled()) {

				if (bitmap != null) {
					Log.d("RecyclingImageView", "bitmap is Recycled ");
				}

				return;

			}

		} else if (drawable instanceof BitmapDrawable) {

			Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();

			if (bitmap != null && bitmap.isRecycled()) {

				if (bitmap != null) {
					Log.d("RecyclingImageView", "bitmap is Recycled ");
				}

				return;

			}
		}

		super.onDraw(canvas);
	}

	/**
	 * @see android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)
	 */
	@Override
	public void setImageDrawable(Drawable drawable) {
		// Keep hold of previous Drawable
		final Drawable previousDrawable = getDrawable();

		// Call super to set new Drawable
		super.setImageDrawable(drawable);

		// Notify new Drawable that it is being displayed
		notifyDrawable(drawable, true);

		// Notify old Drawable so it is no longer being displayed
		notifyDrawable(previousDrawable, false);
	}

	/**
	 * Notifies the drawable that it's displayed state has changed.
	 * 
	 * @param drawable
	 * @param isDisplayed
	 */
	private static void notifyDrawable(Drawable drawable,
			final boolean isDisplayed) {
		if (drawable instanceof RecyclingBitmapDrawable) {
			// The drawable is a CountingBitmapDrawable, so notify it
			((RecyclingBitmapDrawable) drawable).setIsDisplayed(isDisplayed);
		} else if (drawable instanceof LayerDrawable) {
			// The drawable is a LayerDrawable, so recurse on each layer
			LayerDrawable layerDrawable = (LayerDrawable) drawable;
			for (int i = 0, z = layerDrawable.getNumberOfLayers(); i < z; i++) {
				notifyDrawable(layerDrawable.getDrawable(i), isDisplayed);
			}
		}
	}

}
